library(ggplot2)
library(ggthemes)
library(reshape2)
library(dplyr)
library(readxl)
library(gridExtra)
theme_set(theme_stata())
sc_eqtl <- read_xlsx("/Users/kathryntsai/OneDrive\ -\ Villanova\ University/College/2018-2019/Summer\ 2019/TFs_eQTLs_Research/RProjects/Project2/IMPACT/NIHMS76345-supplement-Supplementary_table_2_vanderWijst.xlsx", skip=1)

-
/
                                                                                                                                             

ALL SINGLE CELL DATA

gg1 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(alpha=.8, aes(x=-log(value), fill=variable)) + ggtitle("P-values of eQTLs, grouped by cell type - all sc-eQTLs") # possibly take out position="identity" 
gg2 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of each cell type at each p-value - all sc-eQTLs") # possibly take out position="identity" 
gg3 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(alpha=.8, aes(x=value, fill=variable)) + ggtitle("# eQTLs Significant at FDR < 0.05 by Cell Type - all sc-eQTLs") # possibly take out position="identity" 
gg4 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of Cell Types eQTLs Significant at FDR < 0.05") # possibly take out position="identity" 
# No PBMCs
gg5 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(alpha=.8, aes(x=-log(value), fill=variable)) + ggtitle("P-values of eQTLs, grouped by cell type - all sc-eQTLs, no PBMCs") # possibly take out position="identity" 
gg6 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of each cell type at each p-value - all sc-eQTLs, no PBMCs") # possibly take out position="identity" 
gg7 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(alpha=.8, aes(x=value, fill=variable)) + ggtitle("# eQTLs Significant at FDR < 0.05 by Cell Type - all sc-eQTLs, no PBMCs") # possibly take out position="identity" 
gg8 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of Cell Types eQTLs Significant at FDR < 0.05 - all sc-eQTLs, no PBMCs") # possibly take out position="identity" 
grid.arrange(gg1, gg2, gg3, gg4, gg5, gg6, gg7, gg8, nrow=2)

How many SNP-gene associations exist in both single cell and bulk datasets?

g <-
  merge(
    sc_eqtl,
    franke_cis_data,
    by = c("SNP", "Gene"),
    all.x = F,
    all.y = F
  )
dim(g)
[1] 317  46
# 317 overlap

Of these overlapping associations, are they more or less cell type specific than the associations that can only be detected in the single cell data?

gg9 <- melt(g, 
           id.vars=c("SNP", "Gene"), 
           #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
           measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
      ) %>% 
      ggplot() + geom_histogram(alpha=.8, aes(x=-log(value), fill=variable)) + ggtitle("P-values of eQTLs, grouped by cell type") # possibly take out position="identity" 
gg10 <- melt(g, 
           id.vars=c("SNP", "Gene"), 
           #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
           measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of each cell type at each p-value") # possibly take out position="identity" 
gg11 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(alpha=.8, aes(x=value, fill=variable)) + ggtitle("# eQTLs Significant at FDR < 0.05 by Cell Type") # possibly take out position="identity" 
gg12 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of Cell Types eQTLs Significant at FDR < 0.05") # possibly take out position="identity" 
# No PBMCs
gg13 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(alpha=.8, aes(x=-log(value), fill=variable)) + ggtitle("P-values of eQTLs, grouped by cell type") # possibly take out position="identity" 
gg14 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_histogram(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of each cell type at each p-value") # possibly take out position="identity" 
gg15 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(alpha=.8, aes(x=value, fill=variable)) + ggtitle("# eQTLs Significant at FDR < 0.05 by Cell Type") # possibly take out position="identity" 
gg16 <- melt(g, 
            id.vars=c("SNP", "Gene"), 
            measure.vars = c("T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "cMono__1")
            #measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "cMono")
) %>% 
  ggplot() + geom_bar(position="fill", alpha=.8, aes(x=value, fill=variable)) + ggtitle("Proportions of Cell Types eQTLs Significant at FDR < 0.05") # possibly take out position="identity" 
pdf("sc_eqtl_visualization.pdf", height=24, width=50)
grid.arrange(gg9, gg10, gg11, gg12)
grid.arrange(gg13, gg14, gg15, gg16)
dev.off()

Making a Heat Map

https://slowkow.com/notes/pheatmap-tutorial/

library(pheatmap)
library(RColorBrewer)
library(viridis)

gg17 <- melt(sc_eqtl, 
            id.vars=c("SNP", "Gene"), 
            #measure.vars = c("PBMC__1","T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1", "cMono__1", "ncMono__1")
            measure.vars = c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "Mono")
)

mat_col <- data.table(gg17$variable)
mat_colors <- list(group = brewer.pal(length(unique(gg17$variable)), "Set1"))
names(mat_colors$group) <- unique(gg17$variable)

quantile_breaks <- function(xs, n = 10) {
  breaks <- quantile(xs, probs = seq(0, 1, length.out = n))
  breaks[!duplicated(breaks)]
}

mat_breaks <- quantile_breaks(mat, n = 11)


draw_colnames_45 <- function (coln, gaps, ...) {
  coord <- pheatmap:::find_coordinates(length(coln), gaps)
  x     <- coord$coord - 0.5 * coord$size
  res   <- grid::textGrob(
    coln, x = x, y = unit(1, "npc") - unit(3,"bigpts"),
    vjust = 0.75, hjust = 1, rot = 45, gp = grid::gpar(...)
  )
  return(res)
}
assignInNamespace(
  x = "draw_colnames",
  value = "draw_colnames_45",
  ns = asNamespace("pheatmap")
)

gg17

pdf("sc_eqtl_pheatmap.pdf", height=24, width=50)
pheatmap(
  mat               = -log10(sc_eqtl[, c("PBMC","T CD4+", "T CD8+", "NK", "B", "DC", "Mono")]),
  color             = inferno(length(mat_breaks) -1),
  breaks            = mat_breaks,
  border_color      = F,
  cellwidth = 15,
  cellheight= 3,
  legend = TRUE,
  show_colnames     = T,
  show_rownames     = F,
  treeheight_row = 0,
  treeheight_col = 0,
  annotation_names_col    =  data.table(group = unique(gg17$variable)),
  annotation_legend = TRUE,
  #annotation_names_row = data.table(group = paste0(gg17$SNP, "-", gg17$Gene)),
  annotation_colors = mat_colors,
  drop_levels       = TRUE,
  fontsize          = 3,
  main              = "Quantile Color Scale with Log Values"
)
dev.off()
gg19_new <- gg19 %>% 
  # mutate(state=factor(state,levels=rev(sort(unique(state))))) %>%
  mutate(new_value = cut(gg19$value,breaks=8, labels=c("<0.001", 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875))) #%>% 
The `printer` argument is deprecated as of rlang 0.3.0.
This warning is displayed once per session.
gg19_plot + theme_grey(base_size=8) +
  #theme options
  theme(
    #bold font for legend text
    legend.text=element_text(face="bold"),
    #set thickness of axis ticks
    axis.ticks=element_line(size=0.4),
    axis.text.x = element_text(size=1, angle = 45, hjust = 1),
    #remove plot background
    plot.background=element_blank(),
    #remove plot border
    panel.border=element_blank()
  )

png("test_heatmap3.png")#, height = 1000, width = 1280)
y3 <- heatmap.2(-log10(sc_eqtl_plot3), title(main = "cis eQTLs by Cell Type, non-overlap with cis eQTLs", 10), #ColSideColors = map_color_mat_ordered[,2],  labCol = map_color_mat_ordered[,3],
              cex.main = 1, trace = "none", adjCol = 1, adjRow = 0, labCol = cols3,cexRow=1, 
              labRow = rows3, dendrogram = "none", Rowv = F, Colv = F, col = rev(brewer.pal(9,"YlGnBu")),
              cexCol = 1, srtCol = 90, 
              key = T, keysize=2,key.title = "P-value of eQTL for each cell type", key.xlab = "-log10(P-value)",
              density.info = c("none"),margins=c(14, 14),
              sepcolor = "gray", 
              sepwidth=c(0.005,0.005), 
              rowsep=1:ncol(sc_eqtl_plot3),
              colsep=1:nrow(sc_eqtl_plot3))
dev.off()
null device 
          1 
png("test_heatmap.png") # height= 1000, width=1280
y <- heatmap.2(sc_eqtl_plot, title(main = "cis eQTLs by Cell Type", 10), #ColSideColors = map_color_mat_ordered[,2],  labCol = map_color_mat_ordered[,3],
              cex.main = 10, trace = "none", adjCol = 1, adjRow = 0, labCol = cols,cexRow=3, 
              labRow = rows, dendrogram = "none", Rowv = F, Colv = F, #col = rev(brewer.pal(8,"YlGnBu"))
              cexCol = 3, srtCol = 90, 
              key = T, keysize=2,key.title = "P-value of eQTL for each cell type", key.xlab = "P-value",
              density.info = c("none"),margins=c(14, 14),
              sepcolor = "black", 
              sepwidth=c(0.1,0.1), 
              colsep=1:nrow(sc_eqtl_plot),
              rowsep=1:ncol(sc_eqtl_plot)
      )
dev.off()
null device 
          1 
Warning in gzfile(file, "wb") :
  cannot open compressed file '/Users/kathryntsai/OneDrive - Villanova University/College/2018-2019/Summer 2019/TFs_eQTLs_Research/RProjects/Project2/.Rproj.user/shared/notebooks/3CDBF725-single_cell_investigation/1/FEC238FDE19E1822/ce3mtgst2t7bv_t/4fc82b9b2079495bb9e59b2918158cff.snapshot', probable reason 'No such file or directory'
Error in gzfile(file, "wb") : cannot open the connection
g0 <- sc_eqtl[, c("PBMC__1", "T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1")]
cols <- colnames(g0)
sig_sc <- sapply(g0, sub, pattern='\\*', replacement=1)
sig_sc[is.na(sig_sc)] <- 0
g111 <- sig_sc
g111 <- matrix(as.numeric(g111), nrow=nrow(g0), ncol=ncol(g0))
a1 <- data.table(rowSums(g111))
colnames(a1)<- "a"
nrow(a1[which(a1$a == 1)])
[1] 178
g22 <- g[, c("PBMC__1", "T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1")]
cols <- colnames(g22)
g222 <- sapply(g22, sub, pattern='\\*', replacement=1)
g222[is.na(g222)] <- 0
g222 <- matrix(as.numeric(g222), nrow=nrow(g22), ncol=ncol(g22))
a2 <- data.table(rowSums(g222))
colnames(a2)<- "a"
nrow(a2[which(a2$a == 1)])
[1] 137
g33 <- g2[, c("PBMC__1", "T CD4+__1", "T CD8+__1", "NK__1", "B__1", "DC__1", "Mono__1")]
cols <- colnames(g33)
g333 <- sapply(g33, sub, pattern='\\*', replacement=1)
g333[is.na(g333)] <- 0
g333 <- matrix(as.numeric(g333), nrow=nrow(g33), ncol=ncol(g33))
a3 <- data.table(rowSums(g333))
colnames(a3)<- "a"
nrow(a3[which(a3$a == 1)])
[1] 41

Do we even need sc-eQTLs if we can use IMPACT to identify the cell type?

Since Pfizer eQTLs are found in whole blood, can we use IMPACT to infer cell-type-specificity? Since eQTLgen eQTLs are found in peripheral blood, can we use IMPACT to infer cell-type-specificity?

After learning from the annotation analyses above, can we predict if a given SNP will participate in a cis or trans eQTL?

Consider 3 groups of SNPs: only cis, only trans, both cis and trans (with two separate genes, of course)

What are the models of these datasets? Do all include expression PCs? Traditionally, expression PCs don’t take away signal from cis eQTLs but they might from trans eQTLs. Need to know data details, e.g. how many donors? How many samples? How many cells?

proportion of pbmcs are different cells

LS0tCnRpdGxlOiAiU2luZ2xlIENlbGwgSW52ZXN0aWdhdGlvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3IgbG9hZF9saWJyYXJpZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShyZXNoYXBlMikKbGlicmFyeShkcGx5cikKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZ3JpZEV4dHJhKQp0aGVtZV9zZXQodGhlbWVfc3RhdGEoKSkKCmBgYAoKYGBge3IgbG9hZF9zY19kYXRhLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzY19lcXRsIDwtIHJlYWRfeGxzeCgiL1VzZXJzL2thdGhyeW50c2FpL09uZURyaXZlXCAtXCBWaWxsYW5vdmFcIFVuaXZlcnNpdHkvQ29sbGVnZS8yMDE4LTIwMTkvU3VtbWVyXCAyMDE5L1RGc19lUVRMc19SZXNlYXJjaC9SUHJvamVjdHMvUHJvamVjdDIvSU1QQUNUL05JSE1TNzYzNDUtc3VwcGxlbWVudC1TdXBwbGVtZW50YXJ5X3RhYmxlXzJfdmFuZGVyV2lqc3QueGxzeCIsIHNraXA9MSkKYGBgCgojIEFMTCBTSU5HTEUgQ0VMTCBEQVRBCgpgYGB7ciBjcmVhdGVfcGxvdHNfMn0KZ2cxIDwtIG1lbHQoc2NfZXF0bCwgCiAgICAgICAgICAgIGlkLnZhcnM9YygiU05QIiwgIkdlbmUiKSwgCiAgICAgICAgICAgICNtZWFzdXJlLnZhcnMgPSBjKCJQQk1DX18xIiwiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgIk1vbm9fXzEiLCAiY01vbm9fXzEiLCAibmNNb25vX18xIikKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiUEJNQyIsIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0oYWxwaGE9LjgsIGFlcyh4PS1sb2codmFsdWUpLCBmaWxsPXZhcmlhYmxlKSkgKyBnZ3RpdGxlKCJQLXZhbHVlcyBvZiBlUVRMcywgZ3JvdXBlZCBieSBjZWxsIHR5cGUgLSBhbGwgc2MtZVFUTHMiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpnZzIgPC0gbWVsdChzY19lcXRsLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiTW9ub19fMSIsICJjTW9ub19fMSIsICJuY01vbm9fXzEiKQogICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBjKCJQQk1DIiwiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgImNNb25vIikKKSAlPiUgCiAgZ2dwbG90KCkgKyBnZW9tX2hpc3RvZ3JhbShwb3NpdGlvbj0iZmlsbCIsIGFscGhhPS44LCBhZXMoeD12YWx1ZSwgZmlsbD12YXJpYWJsZSkpICsgZ2d0aXRsZSgiUHJvcG9ydGlvbnMgb2YgZWFjaCBjZWxsIHR5cGUgYXQgZWFjaCBwLXZhbHVlIC0gYWxsIHNjLWVRVExzIikgIyBwb3NzaWJseSB0YWtlIG91dCBwb3NpdGlvbj0iaWRlbnRpdHkiIAoKZ2czIDwtIG1lbHQoc2NfZXF0bCwgCiAgICAgICAgICAgIGlkLnZhcnM9YygiU05QIiwgIkdlbmUiKSwgCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiY01vbm9fXzEiKQogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQyIsIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9iYXIoYWxwaGE9LjgsIGFlcyh4PXZhbHVlLCBmaWxsPXZhcmlhYmxlKSkgKyBnZ3RpdGxlKCIjIGVRVExzIFNpZ25pZmljYW50IGF0IEZEUiA8IDAuMDUgYnkgQ2VsbCBUeXBlIC0gYWxsIHNjLWVRVExzIikgIyBwb3NzaWJseSB0YWtlIG91dCBwb3NpdGlvbj0iaWRlbnRpdHkiIAoKZ2c0IDwtIG1lbHQoc2NfZXF0bCwgCiAgICAgICAgICAgIGlkLnZhcnM9YygiU05QIiwgIkdlbmUiKSwgCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiY01vbm9fXzEiKQogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQyIsIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIlByb3BvcnRpb25zIG9mIENlbGwgVHlwZXMgZVFUTHMgU2lnbmlmaWNhbnQgYXQgRkRSIDwgMC4wNSIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCgojIE5vIFBCTUNzCgpnZzUgPC0gbWVsdChzY19lcXRsLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiTW9ub19fMSIsICJjTW9ub19fMSIsICJuY01vbm9fXzEiKQogICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBjKCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGFscGhhPS44LCBhZXMoeD0tbG9nKHZhbHVlKSwgZmlsbD12YXJpYWJsZSkpICsgZ2d0aXRsZSgiUC12YWx1ZXMgb2YgZVFUTHMsIGdyb3VwZWQgYnkgY2VsbCB0eXBlIC0gYWxsIHNjLWVRVExzLCBubyBQQk1DcyIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCmdnNiA8LSBtZWx0KHNjX2VxdGwsIAogICAgICAgICAgICBpZC52YXJzPWMoIlNOUCIsICJHZW5lIiksIAogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIiwgImNNb25vX18xIiwgIm5jTW9ub19fMSIpCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb249ImZpbGwiLCBhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIlByb3BvcnRpb25zIG9mIGVhY2ggY2VsbCB0eXBlIGF0IGVhY2ggcC12YWx1ZSAtIGFsbCBzYy1lUVRMcywgbm8gUEJNQ3MiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpnZzcgPC0gbWVsdChzY19lcXRsLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgImNNb25vX18xIikKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21fYmFyKGFscGhhPS44LCBhZXMoeD12YWx1ZSwgZmlsbD12YXJpYWJsZSkpICsgZ2d0aXRsZSgiIyBlUVRMcyBTaWduaWZpY2FudCBhdCBGRFIgPCAwLjA1IGJ5IENlbGwgVHlwZSAtIGFsbCBzYy1lUVRMcywgbm8gUEJNQ3MiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpnZzggPC0gbWVsdChzY19lcXRsLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgImNNb25vX18xIikKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgYWxwaGE9LjgsIGFlcyh4PXZhbHVlLCBmaWxsPXZhcmlhYmxlKSkgKyBnZ3RpdGxlKCJQcm9wb3J0aW9ucyBvZiBDZWxsIFR5cGVzIGVRVExzIFNpZ25pZmljYW50IGF0IEZEUiA8IDAuMDUgLSBhbGwgc2MtZVFUTHMsIG5vIFBCTUNzIikgIyBwb3NzaWJseSB0YWtlIG91dCBwb3NpdGlvbj0iaWRlbnRpdHkiIApgYGAKCmBgYHtyIHBsb3Rfc2NfZGF0YSwgZmlnLmhlaWdodD0xMDAsIGZpZy53aWR0aD0yMDAsIHdhcm5pbmc9RkFMU0V9CmdyaWQuYXJyYW5nZShnZzEsIGdnMiwgZ2czLCBnZzQsIGdnNSwgZ2c2LCBnZzcsIGdnOCwgbnJvdz0yKQpgYGAKCiMgSG93IG1hbnkgU05QLWdlbmUgYXNzb2NpYXRpb25zIGV4aXN0IGluIGJvdGggc2luZ2xlIGNlbGwgYW5kIGJ1bGsgZGF0YXNldHM/CgpgYGB7ciBtZXJnZV9kYXRhfQpnIDwtCiAgbWVyZ2UoCiAgICBzY19lcXRsLAogICAgZnJhbmtlX2Npc19kYXRhLAogICAgYnkgPSBjKCJTTlAiLCAiR2VuZSIpLAogICAgYWxsLnggPSBGLAogICAgYWxsLnkgPSBGCiAgKQoKZGltKGcpCiMgMzE3IG92ZXJsYXAKYGBgCgojIyBPZiB0aGVzZSBvdmVybGFwcGluZyBhc3NvY2lhdGlvbnMsIGFyZSB0aGV5IG1vcmUgb3IgbGVzcyBjZWxsIHR5cGUgc3BlY2lmaWMgdGhhbiB0aGUgYXNzb2NpYXRpb25zIHRoYXQgY2FuIG9ubHkgYmUgZGV0ZWN0ZWQgaW4gdGhlIHNpbmdsZSBjZWxsIGRhdGE/CgpgYGB7ciBjcmVhdGVfcGxvdHNfMX0gIApnZzkgPC0gbWVsdChnLCAKICAgICAgICAgICBpZC52YXJzPWMoIlNOUCIsICJHZW5lIiksIAogICAgICAgICAgICNtZWFzdXJlLnZhcnMgPSBjKCJQQk1DX18xIiwiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgIk1vbm9fXzEiLCAiY01vbm9fXzEiLCAibmNNb25vX18xIikKICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBjKCJQQk1DIiwiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgImNNb25vIikKICAgICAgKSAlPiUgCiAgICAgIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0oYWxwaGE9LjgsIGFlcyh4PS1sb2codmFsdWUpLCBmaWxsPXZhcmlhYmxlKSkgKyBnZ3RpdGxlKCJQLXZhbHVlcyBvZiBlUVRMcywgZ3JvdXBlZCBieSBjZWxsIHR5cGUiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpnZzEwIDwtIG1lbHQoZywgCiAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIiwgImNNb25vX18xIiwgIm5jTW9ub19fMSIpCiAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiUEJNQyIsIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb249ImZpbGwiLCBhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIlByb3BvcnRpb25zIG9mIGVhY2ggY2VsbCB0eXBlIGF0IGVhY2ggcC12YWx1ZSIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCmdnMTEgPC0gbWVsdChnLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJjTW9ub19fMSIpCiAgICAgICAgICAgICNtZWFzdXJlLnZhcnMgPSBjKCJQQk1DIiwiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgImNNb25vIikKKSAlPiUgCiAgZ2dwbG90KCkgKyBnZW9tX2JhcihhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIiMgZVFUTHMgU2lnbmlmaWNhbnQgYXQgRkRSIDwgMC4wNSBieSBDZWxsIFR5cGUiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpnZzEyIDwtIG1lbHQoZywgCiAgICAgICAgICAgIGlkLnZhcnM9YygiU05QIiwgIkdlbmUiKSwgCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiY01vbm9fXzEiKQogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQyIsIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIlByb3BvcnRpb25zIG9mIENlbGwgVHlwZXMgZVFUTHMgU2lnbmlmaWNhbnQgYXQgRkRSIDwgMC4wNSIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCiMgTm8gUEJNQ3MKCmdnMTMgPC0gbWVsdChnLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUNfXzEiLCJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiTW9ub19fMSIsICJjTW9ub19fMSIsICJuY01vbm9fXzEiKQogICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBjKCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGFscGhhPS44LCBhZXMoeD0tbG9nKHZhbHVlKSwgZmlsbD12YXJpYWJsZSkpICsgZ2d0aXRsZSgiUC12YWx1ZXMgb2YgZVFUTHMsIGdyb3VwZWQgYnkgY2VsbCB0eXBlIikgIyBwb3NzaWJseSB0YWtlIG91dCBwb3NpdGlvbj0iaWRlbnRpdHkiIAoKZ2cxNCA8LSBtZWx0KGcsIAogICAgICAgICAgICBpZC52YXJzPWMoIlNOUCIsICJHZW5lIiksIAogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIiwgImNNb25vX18xIiwgIm5jTW9ub19fMSIpCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJjTW9ubyIpCikgJT4lIAogIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0ocG9zaXRpb249ImZpbGwiLCBhbHBoYT0uOCwgYWVzKHg9dmFsdWUsIGZpbGw9dmFyaWFibGUpKSArIGdndGl0bGUoIlByb3BvcnRpb25zIG9mIGVhY2ggY2VsbCB0eXBlIGF0IGVhY2ggcC12YWx1ZSIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCmdnMTUgPC0gbWVsdChnLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgImNNb25vX18xIikKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21fYmFyKGFscGhhPS44LCBhZXMoeD12YWx1ZSwgZmlsbD12YXJpYWJsZSkpICsgZ2d0aXRsZSgiIyBlUVRMcyBTaWduaWZpY2FudCBhdCBGRFIgPCAwLjA1IGJ5IENlbGwgVHlwZSIpICMgcG9zc2libHkgdGFrZSBvdXQgcG9zaXRpb249ImlkZW50aXR5IiAKCmdnMTYgPC0gbWVsdChnLCAKICAgICAgICAgICAgaWQudmFycz1jKCJTTlAiLCAiR2VuZSIpLCAKICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gYygiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgImNNb25vX18xIikKICAgICAgICAgICAgI21lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiY01vbm8iKQopICU+JSAKICBnZ3Bsb3QoKSArIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgYWxwaGE9LjgsIGFlcyh4PXZhbHVlLCBmaWxsPXZhcmlhYmxlKSkgKyBnZ3RpdGxlKCJQcm9wb3J0aW9ucyBvZiBDZWxsIFR5cGVzIGVRVExzIFNpZ25pZmljYW50IGF0IEZEUiA8IDAuMDUiKSAjIHBvc3NpYmx5IHRha2Ugb3V0IHBvc2l0aW9uPSJpZGVudGl0eSIgCgpgYGAKCmBgYHtyIHBsb3Rfb3ZlcmxhcHBpbmdfZGF0YX0KcGRmKCJzY19lcXRsX3Zpc3VhbGl6YXRpb24ucGRmIiwgaGVpZ2h0PTI0LCB3aWR0aD01MCkKZ3JpZC5hcnJhbmdlKGdnOSwgZ2cxMCwgZ2cxMSwgZ2cxMikKZ3JpZC5hcnJhbmdlKGdnMTMsIGdnMTQsIGdnMTUsIGdnMTYpCmRldi5vZmYoKQpgYGAKCiMgTWFraW5nIGEgSGVhdCBNYXAKaHR0cHM6Ly9zbG93a293LmNvbS9ub3Rlcy9waGVhdG1hcC10dXRvcmlhbC8KCmBgYHtyIHNjX2VxdGxfaGVhdG1hcF8xfQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeSh2aXJpZGlzKQoKZ2cxNyA8LSBtZWx0KHNjX2VxdGwsIAogICAgICAgICAgICBpZC52YXJzPWMoIlNOUCIsICJHZW5lIiksIAogICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIiwgImNNb25vX18xIiwgIm5jTW9ub19fMSIpCiAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiTW9ubyIpCikKCm1hdF9jb2wgPC0gZGF0YS50YWJsZShnZzE3JHZhcmlhYmxlKQptYXRfY29sb3JzIDwtIGxpc3QoZ3JvdXAgPSBicmV3ZXIucGFsKGxlbmd0aCh1bmlxdWUoZ2cxNyR2YXJpYWJsZSkpLCAiU2V0MSIpKQpuYW1lcyhtYXRfY29sb3JzJGdyb3VwKSA8LSB1bmlxdWUoZ2cxNyR2YXJpYWJsZSkKCnF1YW50aWxlX2JyZWFrcyA8LSBmdW5jdGlvbih4cywgbiA9IDEwKSB7CiAgYnJlYWtzIDwtIHF1YW50aWxlKHhzLCBwcm9icyA9IHNlcSgwLCAxLCBsZW5ndGgub3V0ID0gbikpCiAgYnJlYWtzWyFkdXBsaWNhdGVkKGJyZWFrcyldCn0KCm1hdF9icmVha3MgPC0gcXVhbnRpbGVfYnJlYWtzKG1hdCwgbiA9IDExKQoKCmRyYXdfY29sbmFtZXNfNDUgPC0gZnVuY3Rpb24gKGNvbG4sIGdhcHMsIC4uLikgewogIGNvb3JkIDwtIHBoZWF0bWFwOjo6ZmluZF9jb29yZGluYXRlcyhsZW5ndGgoY29sbiksIGdhcHMpCiAgeCAgICAgPC0gY29vcmQkY29vcmQgLSAwLjUgKiBjb29yZCRzaXplCiAgcmVzICAgPC0gZ3JpZDo6dGV4dEdyb2IoCiAgICBjb2xuLCB4ID0geCwgeSA9IHVuaXQoMSwgIm5wYyIpIC0gdW5pdCgzLCJiaWdwdHMiKSwKICAgIHZqdXN0ID0gMC43NSwgaGp1c3QgPSAxLCByb3QgPSA0NSwgZ3AgPSBncmlkOjpncGFyKC4uLikKICApCiAgcmV0dXJuKHJlcykKfQphc3NpZ25Jbk5hbWVzcGFjZSgKICB4ID0gImRyYXdfY29sbmFtZXMiLAogIHZhbHVlID0gImRyYXdfY29sbmFtZXNfNDUiLAogIG5zID0gYXNOYW1lc3BhY2UoInBoZWF0bWFwIikKKQoKZ2cxNwoKcGRmKCJzY19lcXRsX3BoZWF0bWFwLnBkZiIsIGhlaWdodD0yNCwgd2lkdGg9NTApCnBoZWF0bWFwKAogIG1hdCAgICAgICAgICAgICAgID0gLWxvZzEwKHNjX2VxdGxbLCBjKCJQQk1DIiwiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgIk1vbm8iKV0pLAogIGNvbG9yICAgICAgICAgICAgID0gaW5mZXJubyhsZW5ndGgobWF0X2JyZWFrcykgLTEpLAogIGJyZWFrcyAgICAgICAgICAgID0gbWF0X2JyZWFrcywKICBib3JkZXJfY29sb3IgICAgICA9IEYsCiAgY2VsbHdpZHRoID0gMTUsCiAgY2VsbGhlaWdodD0gMywKICBsZWdlbmQgPSBUUlVFLAogIHNob3dfY29sbmFtZXMgICAgID0gVCwKICBzaG93X3Jvd25hbWVzICAgICA9IEYsCiAgdHJlZWhlaWdodF9yb3cgPSAwLAogIHRyZWVoZWlnaHRfY29sID0gMCwKICBhbm5vdGF0aW9uX25hbWVzX2NvbCAgICA9ICBkYXRhLnRhYmxlKGdyb3VwID0gdW5pcXVlKGdnMTckdmFyaWFibGUpKSwKICBhbm5vdGF0aW9uX2xlZ2VuZCA9IFRSVUUsCiAgI2Fubm90YXRpb25fbmFtZXNfcm93ID0gZGF0YS50YWJsZShncm91cCA9IHBhc3RlMChnZzE3JFNOUCwgIi0iLCBnZzE3JEdlbmUpKSwKICBhbm5vdGF0aW9uX2NvbG9ycyA9IG1hdF9jb2xvcnMsCiAgZHJvcF9sZXZlbHMgICAgICAgPSBUUlVFLAogIGZvbnRzaXplICAgICAgICAgID0gMywKICBtYWluICAgICAgICAgICAgICA9ICJRdWFudGlsZSBDb2xvciBTY2FsZSB3aXRoIExvZyBWYWx1ZXMiCikKZGV2Lm9mZigpCmBgYAoKYGBge3IgbWFrZV9oZWF0bWFwXzIsIGluY2x1ZGU9Rn0KbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGx5cikKZ2cxNyA8LSBtZWx0KHNjX2VxdGwsCiAgICAgICAgICAgICBpZC52YXJzPWMoIlNOUCIsICJHZW5lIiksCiAgICAgICAgICAgICAjbWVhc3VyZS52YXJzID0gYygiUEJNQ19fMSIsIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIiwgImNNb25vX18xIiwgIm5jTW9ub19fMSIpCiAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBjKCJQQk1DIiwiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgIk1vbm8iKQopCmdnMTcgPC0gZGRwbHkoZ2cxNywgLih2YXJpYWJsZSksIHRyYW5zZm9ybSwgcmVzY2FsZSA9IHJlc2NhbGUoLWxvZyh2YWx1ZSkpKQpnZzE3JGVRVEwgPC0gcGFzdGUwKGdnMTckU05QLCBnZzE3JEdlbmUpCmJhc2Vfc2l6ZSA8LSA5CmdnMTdfcGxvdCA8LSBnZ3Bsb3QoZ2cxNywgYWVzKHZhcmlhYmxlLCBlUVRMKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbCA9IHJlc2NhbGUpLCBjb2xvdXIgPSAid2hpdGUiKSArCiAgI3NjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIndoaXRlIiwgaGlnaCA9ICJzdGVlbGJsdWUiKSArCiAgdGhlbWVfZ3JleShiYXNlX3NpemUgPSBiYXNlX3NpemUpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfZWNvbm9taXN0KCkgKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTMpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTgpLAogICAgICAgIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9OCxmYWNlPSJib2xkIiksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMykKICAgICAgICkKIyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGlja3MgPSB0aGVtZV9ibGFuaygpLCBheGlzLnRleHQueCA9IHRoZW1lX3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOCwgYW5nbGUgPSAzMzAsIGhqdXN0ID0gMCwgY29sb3VyID0gImdyZXk1MCIpKQoKZ2cxN19wbG90CgpgYGAKCmBgYHtyIG1ha2VfaGVhdG1hcF8zfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCgpnZzE5X29sZCA8LSBzY19lcXRsW29yZGVyKGFzLm51bWVyaWMoc2NfZXF0bCRQQk1DKSwgZGVjcmVhc2luZz1UKSxdCmdnMTkgPC0gbWVsdChnZzE5X29sZCwKICAgICAgICAgICAgIGlkLnZhcnM9YygiU05QIiwgIkdlbmUiKSwKICAgICAgICAgICAgICNtZWFzdXJlLnZhcnMgPSBjKCJQQk1DX18xIiwiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgIk1vbm9fXzEiLCAiY01vbm9fXzEiLCAibmNNb25vX18xIikKICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IGMoIlBCTUMiLCJUIENENCsiLCAiVCBDRDgrIiwgIk5LIiwgIkIiLCAiREMiLCAiTW9ubyIpCikKZ2cxOSRlUVRMIDwtIHBhc3RlMChnZzE5JFNOUCwgZ2cxOSRHZW5lKQojIGFzc2lnbiB0ZXh0IGNvbG91cgp0ZXh0Y29sIDwtICJncmV5NDAiCgpnZzE5X25ldyA8LSBnZzE5ICU+JSAKICAjIG11dGF0ZShzdGF0ZT1mYWN0b3Ioc3RhdGUsbGV2ZWxzPXJldihzb3J0KHVuaXF1ZShzdGF0ZSkpKSkpICU+JQogIG11dGF0ZShuZXdfdmFsdWUgPSBjdXQoZ2cxOSR2YWx1ZSxicmVha3M9OCwgbGFiZWxzPWMoIjwwLjAwMSIsIDAuMTI1LCAwLjI1LCAwLjM3NSwgMC41LCAwLjYyNSwgMC43NSwgMC44NzUpKSkgIyU+JSAKCiNnZzE5X2JyayA8LSBnZzE5JG5ld192YWx1ZVsxXTooZ2cxOSRuZXdfdmFsdWVbMl0tZ2cxOSRuZXdfdmFsdWVbMV0pLzg6Z2cxOSRuZXdfdmFsdWVbMl0KCmdnMTlfcGxvdCA8LSBnZ3Bsb3QoZ2cxOV9uZXcsbWFwcGluZz1hZXMoeD1lUVRMLHk9dmFyaWFibGUsZmlsbD1uZXdfdmFsdWUpKSsKICBnZW9tX3RpbGUoY29sb3VyPSJ3aGl0ZSIsc2l6ZT0wLjMpKwogIGd1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT0iLWxvZzEwKFAtdmFsdWUpIG9mIGNpcyBlUVRMIGluIGVhY2ggY2VsbCB0eXBlIikpKwogICNyZW1vdmUgeCBhbmQgeSBheGlzIGxhYmVscwogIGxhYnMoeD0iIix5PSIiLCB0aXRsZT0iY2lzIGVRVExzIGluIGVhY2ggY2VsbCB0eXBlIikrCiAgI3JlbW92ZSBleHRyYSBzcGFjZQogICNkZWZpbmUgbmV3IGJyZWFrcyBvbiB4LWF4aXMKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcz1yZXYoYnJld2VyLnBhbCg4LCJZbEduQnUiKSkpICsKICBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZD1jKDAsMCkpKwogIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kPWMoMCwwKSkgI2JyZWFrcz1zZXEoZ2cxOSRuZXdfdmFsdWVbMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZ2cxOSRuZXdfdmFsdWVbMl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjbGVuZ3RoPTgpCiAgI3NldCBhIGJhc2Ugc2l6ZSBmb3IgYWxsIGZvbnRzCiAgCmBgYAoKYGBge3IgcGxvdF9oZWF0bWFwXzN9CmdnMTlfcGxvdCArIHRoZW1lX2dyZXkoYmFzZV9zaXplPTgpICsKICAjdGhlbWUgb3B0aW9ucwogIHRoZW1lKAogICAgI2JvbGQgZm9udCBmb3IgbGVnZW5kIHRleHQKICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChmYWNlPSJib2xkIiksCiAgICAjc2V0IHRoaWNrbmVzcyBvZiBheGlzIHRpY2tzCiAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShzaXplPTAuNCksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEsIGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICAjcmVtb3ZlIHBsb3QgYmFja2dyb3VuZAogICAgcGxvdC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSwKICAgICNyZW1vdmUgcGxvdCBib3JkZXIKICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X2JsYW5rKCkKICApCmBgYAoKYGBge3IgcGxvdF9oZWF0bWFwXzR9CgpsaWJyYXJ5KGdwbG90cykKc2NfZXF0bF9wbG90IDwtIHNjX2VxdGxbLCBjKCJQQk1DIiwgIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJNb25vIildCnNjX2VxdGxfcGxvdCA8LSBkYXRhLm1hdHJpeChzY19lcXRsX3Bsb3QpCnJvd3MgPC0gcGFzdGUoc2NfZXF0bCQiU05QIiwgc2NfZXF0bCQiU3ltYm9sIiwgc2VwPSItIikKI2FwcGx5KHNjX2VxdGwsIDIsIGZ1bmN0aW9uKHgpIHBhc3RlKHgkIlNOUCIsIHgkIlN5bWJvbCIsIHNlcD0iLSIpKQpjb2xzIDwtIGNvbG5hbWVzKHNjX2VxdGxfcGxvdCkKCnBuZygidGVzdF9oZWF0bWFwLnBuZyIpICMgaGVpZ2h0PSAxMDAwLCB3aWR0aD0xMjgwCnkxIDwtIGhlYXRtYXAuMigtbG9nMTAoc2NfZXF0bF9wbG90KSwgdGl0bGUobWFpbiA9ICJjaXMgZVFUTHMgYnkgQ2VsbCBUeXBlIiwgMTApLCAjQ29sU2lkZUNvbG9ycyA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssMl0sICBsYWJDb2wgPSBtYXBfY29sb3JfbWF0X29yZGVyZWRbLDNdLAogICAgICAgICAgICAgIGNleC5tYWluID0gMTAsIHRyYWNlID0gIm5vbmUiLCBhZGpDb2wgPSAxLCBhZGpSb3cgPSAwLCBsYWJDb2wgPSBjb2xzLGNleFJvdz0uMSwgCiAgICAgICAgICAgICAgbGFiUm93ID0gcm93cywgZGVuZHJvZ3JhbSA9ICJub25lIiwgUm93diA9IEYsIENvbHYgPSBGLCBjb2wgPSByZXYoYnJld2VyLnBhbCg5LCJZbEduQnUiKSksCiAgICAgICAgICAgICAgY2V4Q29sID0gMywgc3J0Q29sID0gOTAsIAogICAgICAgICAgICAgIGtleSA9IFQsIGtleXNpemU9MixrZXkudGl0bGUgPSAiUC12YWx1ZSBvZiBlUVRMIGZvciBlYWNoIGNlbGwgdHlwZSIsIGtleS54bGFiID0gIi1sb2cxMChQLXZhbHVlKSIsCiAgICAgICAgICAgICAgZGVuc2l0eS5pbmZvID0gYygibm9uZSIpLG1hcmdpbnM9YygxNCwgMTQpLAogICAgICAgICAgICAgIHNlcGNvbG9yID0gImdyYXkiLCAKICAgICAgICAgICAgICBzZXB3aWR0aD1jKDAuMDA1LDAuMDA1KSwgCiAgICAgICAgICAgICAgcm93c2VwPTE6bmNvbChzY19lcXRsX3Bsb3QpLAogICAgICAgICAgICAgIGNvbHNlcD0xOm5yb3coc2NfZXF0bF9wbG90KSkKCmRldi5vZmYoKQoKZndyaXRlKGFzLmxpc3Qocm93cyksICJyb3dzLnR4dCIsIHNlcD0iXHQiKQoKIyBPVkVSTEFQUElORyBDSVMgRVFUTCBIRUFUTUFQCmcgPC0KICBtZXJnZSgKICAgIHNjX2VxdGwsCiAgICBmcmFua2VfY2lzX2RhdGEsCiAgICBieSA9IGMoIlNOUCIsICJHZW5lIiksCiAgICBhbGwueCA9IEYsCiAgICBhbGwueSA9IEYKICApCgpzY19lcXRsX3Bsb3QyIDwtIGdbLCBjKCJQQk1DIiwgIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJNb25vIildCnNjX2VxdGxfcGxvdDIgPC0gZGF0YS5tYXRyaXgoc2NfZXF0bF9wbG90MikKcm93czIgPC0gcGFzdGUoZyQiU05QIiwgZyQiU3ltYm9sIiwgc2VwPSItIikKI2FwcGx5KHNjX2VxdGwsIDIsIGZ1bmN0aW9uKHgpIHBhc3RlKHgkIlNOUCIsIHgkIlN5bWJvbCIsIHNlcD0iLSIpKQpjb2xzMiA8LSBjb2xuYW1lcyhzY19lcXRsX3Bsb3QyKQoKcG5nKCJ0ZXN0X2hlYXRtYXAyLnBuZyIpIywgaGVpZ2h0ID0gMTAwMCwgd2lkdGggPSAxMjgwKQp5MiA8LSBoZWF0bWFwLjIoLWxvZzEwKHNjX2VxdGxfcGxvdDIpLCB0aXRsZShtYWluID0gImNpcyBlUVRMcyBieSBDZWxsIFR5cGUsIG92ZXJsYXAgd2l0aCBjaXMgZVFUTHMiLCAxMCksICNDb2xTaWRlQ29sb3JzID0gbWFwX2NvbG9yX21hdF9vcmRlcmVkWywyXSwgIGxhYkNvbCA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssM10sCiAgICAgICAgICAgICAgY2V4Lm1haW4gPSAuMSwgdHJhY2UgPSAibm9uZSIsIGFkakNvbCA9IDEsIGFkalJvdyA9IDAsIGxhYkNvbCA9IGNvbHMyLGNleFJvdz0uMSwgCiAgICAgICAgICAgICAgbGFiUm93ID0gcm93czIsIGRlbmRyb2dyYW0gPSAibm9uZSIsIFJvd3YgPSBGLCBDb2x2ID0gRiwgY29sID0gcmV2KGJyZXdlci5wYWwoOSwiWWxHbkJ1IikpLAogICAgICAgICAgICAgIGNleENvbCA9IC4xLCBzcnRDb2wgPSA5MCwgCiAgICAgICAgICAgICAga2V5ID0gVCwga2V5c2l6ZT0yLGtleS50aXRsZSA9ICJQLXZhbHVlIG9mIGVRVEwgZm9yIGVhY2ggY2VsbCB0eXBlIiwga2V5LnhsYWIgPSAiLWxvZzEwKFAtdmFsdWUpIiwKICAgICAgICAgICAgICBkZW5zaXR5LmluZm8gPSBjKCJub25lIiksbWFyZ2lucz1jKDE0LCAxNCksCiAgICAgICAgICAgICAgc2VwY29sb3IgPSAiZ3JheSIsIAogICAgICAgICAgICAgIHNlcHdpZHRoPWMoMC4wMDUsMC4wMDUpLCAKICAgICAgICAgICAgICByb3dzZXA9MTpuY29sKHNjX2VxdGxfcGxvdDIpLAogICAgICAgICAgICAgIGNvbHNlcD0xOm5yb3coc2NfZXF0bF9wbG90MikpCgpkZXYub2ZmKCkKCmZ3cml0ZShhcy5saXN0KHJvd3MyKSwgInJvd3MyLnR4dCIsIHNlcD0iXHQiKQoKCiMgRVFUTFMgTk9UIElOIElUCmcyIDwtCiAgYW50aV9qb2luKAogICAgc2NfZXF0bCwKICAgIGZyYW5rZV9jaXNfZGF0YSwKICAgIGJ5ID0gYygiU05QIiwgIkdlbmUiKQogICkKCnNjX2VxdGxfcGxvdDMgPC0gZzJbLCBjKCJQQk1DIiwgIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJNb25vIildCnNjX2VxdGxfcGxvdDMgPC0gZGF0YS5tYXRyaXgoc2NfZXF0bF9wbG90MykKcm93czMgPC0gcGFzdGUoZzIkIlNOUCIsIGcyJCJTeW1ib2wiLCBzZXA9Ii0iKQojYXBwbHkoc2NfZXF0bCwgMiwgZnVuY3Rpb24oeCkgcGFzdGUoeCQiU05QIiwgeCQiU3ltYm9sIiwgc2VwPSItIikpCmNvbHMzIDwtIGNvbG5hbWVzKHNjX2VxdGxfcGxvdDMpCgpwbmcoInRlc3RfaGVhdG1hcDMucG5nIikjLCBoZWlnaHQgPSAxMDAwLCB3aWR0aCA9IDEyODApCnkzIDwtIGhlYXRtYXAuMigtbG9nMTAoc2NfZXF0bF9wbG90MyksIHRpdGxlKG1haW4gPSAiY2lzIGVRVExzIGJ5IENlbGwgVHlwZSwgbm9uLW92ZXJsYXAgd2l0aCBjaXMgZVFUTHMiLCAxMCksICNDb2xTaWRlQ29sb3JzID0gbWFwX2NvbG9yX21hdF9vcmRlcmVkWywyXSwgIGxhYkNvbCA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssM10sCiAgICAgICAgICAgICAgY2V4Lm1haW4gPSAxLCB0cmFjZSA9ICJub25lIiwgYWRqQ29sID0gMSwgYWRqUm93ID0gMCwgbGFiQ29sID0gY29sczMsY2V4Um93PTEsIAogICAgICAgICAgICAgIGxhYlJvdyA9IHJvd3MzLCBkZW5kcm9ncmFtID0gIm5vbmUiLCBSb3d2ID0gRiwgQ29sdiA9IEYsIGNvbCA9IHJldihicmV3ZXIucGFsKDksIllsR25CdSIpKSwKICAgICAgICAgICAgICBjZXhDb2wgPSAxLCBzcnRDb2wgPSA5MCwgCiAgICAgICAgICAgICAga2V5ID0gVCwga2V5c2l6ZT0yLGtleS50aXRsZSA9ICJQLXZhbHVlIG9mIGVRVEwgZm9yIGVhY2ggY2VsbCB0eXBlIiwga2V5LnhsYWIgPSAiLWxvZzEwKFAtdmFsdWUpIiwKICAgICAgICAgICAgICBkZW5zaXR5LmluZm8gPSBjKCJub25lIiksbWFyZ2lucz1jKDE0LCAxNCksCiAgICAgICAgICAgICAgc2VwY29sb3IgPSAiZ3JheSIsIAogICAgICAgICAgICAgIHNlcHdpZHRoPWMoMC4wMDUsMC4wMDUpLCAKICAgICAgICAgICAgICByb3dzZXA9MTpuY29sKHNjX2VxdGxfcGxvdDMpLAogICAgICAgICAgICAgIGNvbHNlcD0xOm5yb3coc2NfZXF0bF9wbG90MykpCgpkZXYub2ZmKCkKCnBuZygidGVzdF9oZWF0bWFwNC5wbmciKQp5MQp5Mgp5MwpkZXYub2ZmKCkKCgpgYGAKCmBgYHtyIHBsb3RfaGVhdG1hcF81fQoKbGlicmFyeShncGxvdHMpCnNjX2VxdGxfcGxvdCA8LSBzY19lcXRsWywgYygiUEJNQ19fMSIsICJUIENENCtfXzEiLCAiVCBDRDgrX18xIiwgIk5LX18xIiwgIkJfXzEiLCAiRENfXzEiLCAiTW9ub19fMSIpXQpjb2xzIDwtIGNvbG5hbWVzKHNjX2VxdGxfcGxvdCkKc2lnX3NjIDwtIHNhcHBseShzY19lcXRsX3Bsb3QsIHN1YiwgcGF0dGVybj0nXFwqJywgcmVwbGFjZW1lbnQ9MSkKc2lnX3NjW2lzLm5hKHNpZ19zYyldIDwtIDAKc2NfZXF0bF9wbG90IDwtIGRhdGEubWF0cml4KHNpZ19zYykKc2NfZXF0bF9wbG90IDwtIHNhcHBseShzY19lcXRsX3Bsb3QsIGFzLm51bWVyaWMpCnNjX2VxdGxfcGxvdCA8LSBtYXRyaXgoZGF0YT1zY19lcXRsX3Bsb3QsIG5jb2w9NywgbnJvdz0zOTgpCnJvd3MgPC0gcGFzdGUoc2NfZXF0bCQiU05QIiwgc2NfZXF0bCQiU3ltYm9sIiwgc2VwPSItIikKI2FwcGx5KHNjX2VxdGwsIDIsIGZ1bmN0aW9uKHgpIHBhc3RlKHgkIlNOUCIsIHgkIlN5bWJvbCIsIHNlcD0iLSIpKQoKcG5nKCJ0ZXN0X2hlYXRtYXAucG5nIikgIyBoZWlnaHQ9IDEwMDAsIHdpZHRoPTEyODAKeSA8LSBoZWF0bWFwLjIoc2NfZXF0bF9wbG90LCB0aXRsZShtYWluID0gImNpcyBlUVRMcyBieSBDZWxsIFR5cGUiLCAxMCksICNDb2xTaWRlQ29sb3JzID0gbWFwX2NvbG9yX21hdF9vcmRlcmVkWywyXSwgIGxhYkNvbCA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssM10sCiAgICAgICAgICAgICAgY2V4Lm1haW4gPSAxMCwgdHJhY2UgPSAibm9uZSIsIGFkakNvbCA9IDEsIGFkalJvdyA9IDAsIGxhYkNvbCA9IGNvbHMsY2V4Um93PTMsIAogICAgICAgICAgICAgIGxhYlJvdyA9IHJvd3MsIGRlbmRyb2dyYW0gPSAibm9uZSIsIFJvd3YgPSBGLCBDb2x2ID0gRiwgI2NvbCA9IHJldihicmV3ZXIucGFsKDgsIllsR25CdSIpKQogICAgICAgICAgICAgIGNleENvbCA9IDMsIHNydENvbCA9IDkwLCAKICAgICAgICAgICAgICBrZXkgPSBULCBrZXlzaXplPTIsa2V5LnRpdGxlID0gIlAtdmFsdWUgb2YgZVFUTCBmb3IgZWFjaCBjZWxsIHR5cGUiLCBrZXkueGxhYiA9ICJQLXZhbHVlIiwKICAgICAgICAgICAgICBkZW5zaXR5LmluZm8gPSBjKCJub25lIiksbWFyZ2lucz1jKDE0LCAxNCksCiAgICAgICAgICAgICAgc2VwY29sb3IgPSAiYmxhY2siLCAKICAgICAgICAgICAgICBzZXB3aWR0aD1jKDAuMSwwLjEpLCAKICAgICAgICAgICAgICBjb2xzZXA9MTpucm93KHNjX2VxdGxfcGxvdCksCiAgICAgICAgICAgICAgcm93c2VwPTE6bmNvbChzY19lcXRsX3Bsb3QpCiAgICAgICkKCmRldi5vZmYoKQoKZndyaXRlKGFzLmxpc3Qocm93cyksICJyb3dzLnR4dCIsIHNlcD0iXHQiKQoKIyBPVkVSTEFQUElORyBDSVMgRVFUTCBIRUFUTUFQCmcgPC0KICBtZXJnZSgKICAgIHNjX2VxdGwsCiAgICBmcmFua2VfY2lzX2RhdGEsCiAgICBieSA9IGMoIlNOUCIsICJHZW5lIiksCiAgICBhbGwueCA9IEYsCiAgICBhbGwueSA9IEYKICApCgpzY19lcXRsX3Bsb3QyIDwtIGdbLCBjKCJQQk1DIiwgIlQgQ0Q0KyIsICJUIENEOCsiLCAiTksiLCAiQiIsICJEQyIsICJNb25vIildCnNjX2VxdGxfcGxvdDIgPC0gZGF0YS5tYXRyaXgoc2NfZXF0bF9wbG90MikKcm93czIgPC0gcGFzdGUoZyQiU05QIiwgZyQiU3ltYm9sIiwgc2VwPSItIikKI2FwcGx5KHNjX2VxdGwsIDIsIGZ1bmN0aW9uKHgpIHBhc3RlKHgkIlNOUCIsIHgkIlN5bWJvbCIsIHNlcD0iLSIpKQpjb2xzMiA8LSBjb2xuYW1lcyhzY19lcXRsX3Bsb3QyKQoKcG5nKCJ0ZXN0X2hlYXRtYXAyLnBuZyIpIywgaGVpZ2h0ID0gMTAwMCwgd2lkdGggPSAxMjgwKQp5IDwtIGhlYXRtYXAuMihzY19lcXRsX3Bsb3QyLCB0aXRsZShtYWluID0gImNpcyBlUVRMcyBieSBDZWxsIFR5cGUsIG92ZXJsYXAgd2l0aCBjaXMgZVFUTHMiLCAxMCksICNDb2xTaWRlQ29sb3JzID0gbWFwX2NvbG9yX21hdF9vcmRlcmVkWywyXSwgIGxhYkNvbCA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssM10sCiAgICAgICAgICAgICAgY2V4Lm1haW4gPSAuMSwgdHJhY2UgPSAibm9uZSIsIGFkakNvbCA9IDEsIGFkalJvdyA9IDAsIGxhYkNvbCA9IGNvbHMyLGNleFJvdz0uMSwgCiAgICAgICAgICAgICAgbGFiUm93ID0gcm93czIsIGRlbmRyb2dyYW0gPSAibm9uZSIsIFJvd3YgPSBGLCBDb2x2ID0gRiwgI2NvbCA9IHJldihicmV3ZXIucGFsKDgsIllsR25CdSIpKQogICAgICAgICAgICAgIGNleENvbCA9IC4xLCBzcnRDb2wgPSA5MCwgCiAgICAgICAgICAgICAga2V5ID0gRiwgI2tleXNpemU9MixrZXkudGl0bGUgPSAiUC12YWx1ZSBvZiBlUVRMIGZvciBlYWNoIGNlbGwgdHlwZSIsIGtleS54bGFiID0gIlAtdmFsdWUiLAogICAgICAgICAgICAgIGRlbnNpdHkuaW5mbyA9IGMoIm5vbmUiKSxtYXJnaW5zPWMoMTQsIDE0KSwKICAgICAgICAgICAgICBzZXBjb2xvciA9ICJncmF5IiwgCiAgICAgICAgICAgICAgc2Vwd2lkdGg9YygwLjAwNSwwLjAwNSksIAogICAgICAgICAgICAgIHJvd3NlcD0xOm5jb2woc2NfZXF0bF9wbG90MiksCiAgICAgICAgICAgICAgY29sc2VwPTE6bnJvdyhzY19lcXRsX3Bsb3QyKSkKCmRldi5vZmYoKQoKZndyaXRlKGFzLmxpc3Qocm93czIpLCAicm93czIudHh0Iiwgc2VwPSJcdCIpCgoKIyBFUVRMUyBOT1QgSU4gSVQKZzIgPC0KICBhbnRpX2pvaW4oCiAgICBzY19lcXRsLAogICAgZnJhbmtlX2Npc19kYXRhLAogICAgYnkgPSBjKCJTTlAiLCAiR2VuZSIpCiAgKQoKc2NfZXF0bF9wbG90MyA8LSBnMlssIGMoIlBCTUMiLCAiVCBDRDQrIiwgIlQgQ0Q4KyIsICJOSyIsICJCIiwgIkRDIiwgIk1vbm8iKV0Kc2NfZXF0bF9wbG90MyA8LSBkYXRhLm1hdHJpeChzY19lcXRsX3Bsb3QzKQpyb3dzMyA8LSBwYXN0ZShnMiQiU05QIiwgZzIkIlN5bWJvbCIsIHNlcD0iLSIpCiNhcHBseShzY19lcXRsLCAyLCBmdW5jdGlvbih4KSBwYXN0ZSh4JCJTTlAiLCB4JCJTeW1ib2wiLCBzZXA9Ii0iKSkKY29sczMgPC0gY29sbmFtZXMoc2NfZXF0bF9wbG90MykKCnBuZygidGVzdF9oZWF0bWFwMy5wbmciKSMsIGhlaWdodCA9IDEwMDAsIHdpZHRoID0gMTI4MCkKeSA8LSBoZWF0bWFwLjIobG9nMTAoc2NfZXF0bF9wbG90MyksIHRpdGxlKG1haW4gPSAiY2lzIGVRVExzIGJ5IENlbGwgVHlwZSwgbm9uLW92ZXJsYXAgd2l0aCBjaXMgZVFUTHMiLCAxMCksICNDb2xTaWRlQ29sb3JzID0gbWFwX2NvbG9yX21hdF9vcmRlcmVkWywyXSwgIGxhYkNvbCA9IG1hcF9jb2xvcl9tYXRfb3JkZXJlZFssM10sCiAgICAgICAgICAgICAgY2V4Lm1haW4gPSAxLCB0cmFjZSA9ICJub25lIiwgYWRqQ29sID0gMSwgYWRqUm93ID0gMCwgbGFiQ29sID0gY29sczMsY2V4Um93PTEsIAogICAgICAgICAgICAgIGxhYlJvdyA9IHJvd3MzLCBkZW5kcm9ncmFtID0gIm5vbmUiLCBSb3d2ID0gRiwgQ29sdiA9IEYsICNjb2wgPSByZXYoYnJld2VyLnBhbCg4LCJZbEduQnUiKSkKICAgICAgICAgICAgICBjZXhDb2wgPSAxLCBzcnRDb2wgPSA5MCwgCiAgICAgICAgICAgICAga2V5ID0gRiwgI2tleXNpemU9MixrZXkudGl0bGUgPSAiUC12YWx1ZSBvZiBlUVRMIGZvciBlYWNoIGNlbGwgdHlwZSIsIGtleS54bGFiID0gIlAtdmFsdWUiLAogICAgICAgICAgICAgIGRlbnNpdHkuaW5mbyA9IGMoIm5vbmUiKSxtYXJnaW5zPWMoMTQsIDE0KSwKICAgICAgICAgICAgICBzZXBjb2xvciA9ICJncmF5IiwgCiAgICAgICAgICAgICAgc2Vwd2lkdGg9YygwLjAwNSwwLjAwNSksIAogICAgICAgICAgICAgIHJvd3NlcD0xOm5jb2woc2NfZXF0bF9wbG90MyksCiAgICAgICAgICAgICAgY29sc2VwPTE6bnJvdyhzY19lcXRsX3Bsb3QzKSkKCmRldi5vZmYoKQoKYGBgCgpgYGB7cn0KZzAgPC0gc2NfZXF0bFssIGMoIlBCTUNfXzEiLCAiVCBDRDQrX18xIiwgIlQgQ0Q4K19fMSIsICJOS19fMSIsICJCX18xIiwgIkRDX18xIiwgIk1vbm9fXzEiKV0KY29scyA8LSBjb2xuYW1lcyhnMCkKc2lnX3NjIDwtIHNhcHBseShnMCwgc3ViLCBwYXR0ZXJuPSdcXConLCByZXBsYWNlbWVudD0xKQpzaWdfc2NbaXMubmEoc2lnX3NjKV0gPC0gMApnMTExIDwtIHNpZ19zYwpnMTExIDwtIG1hdHJpeChhcy5udW1lcmljKGcxMTEpLCBucm93PW5yb3coZzApLCBuY29sPW5jb2woZzApKQphMSA8LSBkYXRhLnRhYmxlKHJvd1N1bXMoZzExMSkpCmNvbG5hbWVzKGExKTwtICJhIgpucm93KGExW3doaWNoKGExJGEgPT0gMSldKQoKZzIyIDwtIGdbLCBjKCJQQk1DX18xIiwgIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIildCmNvbHMgPC0gY29sbmFtZXMoZzIyKQpnMjIyIDwtIHNhcHBseShnMjIsIHN1YiwgcGF0dGVybj0nXFwqJywgcmVwbGFjZW1lbnQ9MSkKZzIyMltpcy5uYShnMjIyKV0gPC0gMApnMjIyIDwtIG1hdHJpeChhcy5udW1lcmljKGcyMjIpLCBucm93PW5yb3coZzIyKSwgbmNvbD1uY29sKGcyMikpCmEyIDwtIGRhdGEudGFibGUocm93U3VtcyhnMjIyKSkKY29sbmFtZXMoYTIpPC0gImEiCm5yb3coYTJbd2hpY2goYTIkYSA9PSAxKV0pCgpnMzMgPC0gZzJbLCBjKCJQQk1DX18xIiwgIlQgQ0Q0K19fMSIsICJUIENEOCtfXzEiLCAiTktfXzEiLCAiQl9fMSIsICJEQ19fMSIsICJNb25vX18xIildCmNvbHMgPC0gY29sbmFtZXMoZzMzKQpnMzMzIDwtIHNhcHBseShnMzMsIHN1YiwgcGF0dGVybj0nXFwqJywgcmVwbGFjZW1lbnQ9MSkKZzMzM1tpcy5uYShnMzMzKV0gPC0gMApnMzMzIDwtIG1hdHJpeChhcy5udW1lcmljKGczMzMpLCBucm93PW5yb3coZzMzKSwgbmNvbD1uY29sKGczMykpCmEzIDwtIGRhdGEudGFibGUocm93U3VtcyhnMzMzKSkKY29sbmFtZXMoYTMpPC0gImEiCm5yb3coYTNbd2hpY2goYTMkYSA9PSAxKV0pCgpgYGAKCgojIERvIHdlIGV2ZW4gbmVlZCBzYy1lUVRMcyBpZiB3ZSBjYW4gdXNlIElNUEFDVCB0byBpZGVudGlmeSB0aGUgY2VsbCB0eXBlPwoKIyBTaW5jZSBQZml6ZXIgZVFUTHMgYXJlIGZvdW5kIGluIHdob2xlIGJsb29kLCBjYW4gd2UgdXNlIElNUEFDVCB0byBpbmZlciBjZWxsLXR5cGUtc3BlY2lmaWNpdHk/IFNpbmNlIGVRVExnZW4gZVFUTHMgYXJlIGZvdW5kIGluIHBlcmlwaGVyYWwgYmxvb2QsIGNhbiB3ZSB1c2UgSU1QQUNUIHRvIGluZmVyIGNlbGwtdHlwZS1zcGVjaWZpY2l0eT8KCiMgQWZ0ZXIgbGVhcm5pbmcgZnJvbSB0aGUgYW5ub3RhdGlvbiBhbmFseXNlcyBhYm92ZSwgY2FuIHdlIHByZWRpY3QgaWYgYSBnaXZlbiBTTlAgd2lsbCBwYXJ0aWNpcGF0ZSBpbiBhIGNpcyBvciB0cmFucyBlUVRMPyAKIyBDb25zaWRlciAzIGdyb3VwcyBvZiBTTlBzOiBvbmx5IGNpcywgb25seSB0cmFucywgYm90aCBjaXMgYW5kIHRyYW5zICh3aXRoIHR3byBzZXBhcmF0ZSBnZW5lcywgb2YgY291cnNlKQoKIyBXaGF0IGFyZSB0aGUgbW9kZWxzIG9mIHRoZXNlIGRhdGFzZXRzPyBEbyBhbGwgaW5jbHVkZSBleHByZXNzaW9uIFBDcz8gVHJhZGl0aW9uYWxseSwgZXhwcmVzc2lvbiBQQ3MgZG9u4oCZdCB0YWtlIGF3YXkgc2lnbmFsIGZyb20gY2lzIGVRVExzIGJ1dCB0aGV5IG1pZ2h0IGZyb20gdHJhbnMgZVFUTHMuIE5lZWQgdG8ga25vdyBkYXRhIGRldGFpbHMsIGUuZy4gaG93IG1hbnkgZG9ub3JzPyBIb3cgbWFueSBzYW1wbGVzPyBIb3cgbWFueSBjZWxscz8KCiMgcHJvcG9ydGlvbiBvZiBwYm1jcyBhcmUgZGlmZmVyZW50IGNlbGxz